import sys

import numpy as np
from PIL import Image, ImageDraw, ImageFont


def convert_to_ascii(file):
    try:
        # Open the image file as <im>.
        im = Image.open(file)

    except FileNotFoundError:
        print('找不到该文件！')

    else:
        # Accuracy of sampling.
        sample_rate = 0.15

        try:
            # Compute letter aspect ratio.
            font = ImageFont.truetype('C:/Windows/Fonts/consola.ttf')

        except OSError:
            print('系统Fonts目录下找不到consola字体！')

        else:
            # ratio = width / height.
            aspect_ratio = font.getsize('x')[0] / font.getsize('x')[1]

            # Convert <im> according to the ratio.
            new_im_size = np.array(
                [im.size[0] * sample_rate, im.size[1] * sample_rate * aspect_ratio]
            ).astype(int)
            im = im.resize(new_im_size)

            # Keep a copy of <im> for color sampling.
            im_copy = np.array(im)

            # Convert <im> to gray scale image.
            im = im.convert('L')

            # Convert <im> to numpy array.
            im = np.array(im)

            # Define all the symbols in ascending order.
            symbols = np.array(list('.-vM'))

            # Normalize the values of <im> array to [0, max_symbol_index).
            im = (im - im.min()) / (im.max() - im.min()) * (symbols.size - 1)

            # Generate the ascii picture.
            ascii_pic = symbols[im.astype(int)]

            # Create a picture.
            letter_size = font.getsize('x')
            im_out_size = new_im_size * letter_size
            bg_color = 'black'
            im_out = Image.new('RGB', tuple(im_out_size), bg_color)
            draw = ImageDraw.Draw(im_out)

            # Draw text.
            y = 0
            for i, line in enumerate(ascii_pic):
                for j, ch in enumerate(line):
                    color = tuple(im_copy[i, j])
                    draw.text((letter_size[0] * j, y),
                              ch, fill=color, font=font)
                y += letter_size[1]

            # Save image file.
            im_out.save(file.split('.')[0] + '-ascii.png')


if __name__ == '__main__':
    convert_to_ascii(sys.argv[1])
